#include "mainwindow.h"
#include "homewidget.h"
#include "statuswidget.h"
#include "settingswidget.h"
#include "networkwidget.h"
#include "rcwidget.h"

MainWindow::MainWindow(QWidget *parent, Pages::PagesNumber pageType)
    : QMainWindow(parent)
{
    qDebug() << "desktop width:" << QApplication::desktop()->width();
    qDebug() << "desktop height:" << QApplication::desktop()->height();
    qDebug() << "desktop physicalDpiX:" << QApplication::desktop()->physicalDpiX();
    qDebug() << "desktop physicalDpiY:" << QApplication::desktop()->physicalDpiY();
    qDebug() << "screen0 physicalSize:" << QGuiApplication::screens().at(0)->physicalSize();
    qDebug() << "screen0 physicalDotsPerInch:" << QGuiApplication::screens().at(0)->physicalDotsPerInch();
    qDebug() << "screen0 logicalDotsPerInch:" << QGuiApplication::screens().at(0)->logicalDotsPerInch();
//    this->resize(1280,720);
    this->setWindowTitle("Quad-Guider");
    this->setWindowIcon(QIcon("../resource/main_window_icon.png"));// TODO:支持配置
    // 窗口背景色
    QColor color = QColor(Qt::white);
    QPalette p = this->palette();
    p.setColor(QPalette::Window,color);
    this->setPalette(p);

    mainWindowCentralWidget = new QWidget();
    hBoxLayoutCentralWidget = new QHBoxLayout();
    hBoxLayoutCentralWidget->setMargin(0);
    mainWindowCentralWidget->setLayout(hBoxLayoutCentralWidget);

    // 添加界面内容，连接信号  disconnect是在切换界面和关闭窗口时
    setPageAndConnectButtons(pageType);

    this->setAttribute(Qt::WA_DeleteOnClose);
    this->setCentralWidget(mainWindowCentralWidget);


    //状态栏
    windowStatusBar = statusBar();
    labelStatusArmed = new QLabel();
    labelStatusArmed->setText("Disarmed");
    windowStatusBar->addWidget(labelStatusArmed);
    labelStatusFlyMode = new QLabel();
    labelStatusFlyMode->setText("Attitude");
    windowStatusBar->addWidget(labelStatusFlyMode);
    labelStatusSerialSpeed = new QLabel();
    labelStatusSerialSpeed->setText("Serial:0B/s");
    windowStatusBar->addWidget(labelStatusSerialSpeed);
    labelStatusUDPSpeed = new QLabel();
    labelStatusUDPSpeed->setText("UDP:0B/s");
    windowStatusBar->addWidget(labelStatusUDPSpeed);
    labelStatusFCConnected = new QLabel("FC:Disconnected");
    windowStatusBar->addWidget(labelStatusFCConnected);
    labelStatusHeartbeat = new QLabel("Heartbeat:0");
    windowStatusBar->addWidget(labelStatusHeartbeat);
    labelStatusHostPlatform = new QLabel();
#ifdef __HOST_PLATFORM_WINDOWS_
    labelStatusHostPlatform->setText(QString("Host windows"));
//    labelStatusHostPlatform->adjustSize();
#elif defined __HOST_PLATFORM_LINUX_
    labelStatusHostPlatform->setText(QString("Host linux"));
//    labelStatusHostPlatform->adjustSize();
#else
    labelStatusHostPlatform->setText(QString("Host unknown"));
//    labelStatusHostPlatform->adjustSize();
#endif
    windowStatusBar->addWidget(labelStatusHostPlatform);
}

MainWindow::~MainWindow()
{
//    qDebug() << "File:" <<  __FILE__ << " Line:"<<  __LINE__ << " Func:" <<  __FUNCTION__;
    LOGD("here");
    unsigned int count = getNumberOfAllWindows();
    if(count == 1){
        // 关闭最后一个窗口时，释放全部资源
        LOGI("close the last window now");
        // 先释放带有子线程的
        NetworkWidget::release();
        HomeWidget::release();
        StatusWidget::release();
        SettingsWidget::release();
        // 最后释放log线程
        Log::release();
    }else{
        // 关闭其中一个窗口，释放这个窗口的界面，可被其他窗口使用
        LOGI("close one of %d windows", count);
        removeCurrentWidget();
        disconnectCurrentWidget();
    }
    this->close();
}

int MainWindow::mainWindowSetLayout()
{
    LOGD("here");
    QString buttonString = ((QPushButton*)sender())->text();
    LOGD("button:%s clicked", buttonString.toStdString().data());

    QStringList stringList;
    Pages::setPagesStringList(&stringList);

    if(stringList.indexOf(buttonString) == currentPageNumber){
        qDebug() << "same page, this button should not clicked!!!";
        LOGE("same page, this button should not clicked!!!");
        return -1;
    }

    MainWindow *window = getWindowByPage(Pages::PagesNumber(stringList.indexOf(buttonString)));
    if(window != nullptr){
        LOGI("found another window show the target page, show this window now");
        window->activateWindow();
        window->setWindowState((window->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
        return 0;
    }

    // 把当前显示内容清掉
    removeCurrentWidget();

    // disconnect, 否则按钮可能会连接到两个窗口上
    disconnectCurrentWidget();

    // 显示新的界面
    setPageAndConnectButtons(Pages::PagesNumber(stringList.indexOf(buttonString)));

    return 0;
}

int MainWindow::setPageAndConnectButtons(Pages::PagesNumber pageType)
{
    switch (pageType) {
    case Pages::HomePage:
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&HomeWidget::getInstance());
        currentPageNumber = Pages::HomePage;
        HomeWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    case Pages::StatusPage:
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&StatusWidget::getInstance());
        currentPageNumber = Pages::StatusPage;
        StatusWidget::getInstance().updateWidgetsAfterSetPage();
        StatusWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    case Pages::ChartPage:
        LOGD("here");
        // TODO: addWidget
        currentPageNumber = Pages::ChartPage;
        // TODO: connectButtonsToMainWindow
        break;
    case Pages::FCConfigPage:
        LOGD("here");
        // TODO: addWidget
        currentPageNumber = Pages::FCConfigPage;
        // TODO: connectButtonsToMainWindow
        break;
    case Pages::_2DVisionPage:
        LOGD("here");
        // TODO: addWidget
        currentPageNumber = Pages::_2DVisionPage;
        // TODO: connectButtonsToMainWindow
        break;
    case Pages::_3DViewPage:
        LOGD("here");
        // TODO: addWidget
        currentPageNumber = Pages::_3DViewPage;
        // TODO: connectButtonsToMainWindow
        break;
    case Pages::RCPage:
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&RcWidget::getInstance());
        currentPageNumber = Pages::RCPage;
        RcWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    case Pages::SerialPage:
        LOGD("here");
        // TODO: addWidget
        currentPageNumber = Pages::SerialPage;
        // TODO: connectButtonsToMainWindow
        break;
    case Pages::Networkpage:
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&NetworkWidget::getInstance());
        currentPageNumber = Pages::Networkpage;
        NetworkWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    case Pages::SettingsPage:
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&SettingsWidget::getInstance());
        currentPageNumber = Pages::SettingsPage;
        SettingsWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    default :
        LOGD("here");
        hBoxLayoutCentralWidget->addWidget(&HomeWidget::getInstance());
        currentPageNumber = Pages::HomePage;
        HomeWidget::getInstance().topButtons->connectButtonsToMainWindow(this);
        break;
    }
    return 0;
}

int MainWindow::newWindow()
{
    LOGD("here");
    QString buttonString = ((QPushButton*)sender())->text();
    LOGD("button:%s clicked", buttonString.toStdString().data());

    QStringList stringList;
    Pages::setPagesStringList(&stringList);

    MainWindow *window = getWindowByPage(Pages::PagesNumber(stringList.indexOf(buttonString)));
    if(window != nullptr){
        LOGI("found another window show the target page, show this window now");
        window->activateWindow();
        window->setWindowState((window->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
        return 0;
    }

    unsigned int count = getNumberOfAllWindows();
    // 限制窗口总数，防止卡顿
    if(count <= 4){
        LOGI("open new window now");
        MainWindow *newWindow = new MainWindow(nullptr, Pages::PagesNumber(stringList.indexOf(buttonString)));
        newWindow->show();
    }else{
        qDebug() << "already have " << count << "windows, will not create new window";
        LOGE("already have %d windows, will not create new window", count);
    }
    return 0;
}

int MainWindow::removeCurrentWidget()
{
    if(currentPageNumber == Pages::StatusPage){
        StatusWidget::getInstance().releaseWidgetsWhenPageChanged();
    }

    QLayoutItem * item = hBoxLayoutCentralWidget->itemAt(0);
    QWidget *currentWidget = qobject_cast<QWidget*>(item->widget());
    if(currentWidget == nullptr){
        qDebug() << "currentWidget is null!!!";
        LOGE("currentWidget is null!!!");
        return -1;
    }
    currentWidget->setParent(nullptr);
    hBoxLayoutCentralWidget->removeWidget(currentWidget);
    return 0;
}

int MainWindow::disconnectCurrentWidget()
{
    switch (currentPageNumber) {
    case Pages::HomePage:
        LOGD("here");
        HomeWidget::getInstance().topButtons->disconnectButtonsToMainWindow();
        break;
    case Pages::StatusPage:
        LOGD("here");
        StatusWidget::getInstance().topButtons->disconnectButtonsToMainWindow();
        break;
    case Pages::ChartPage:
        LOGD("here");
        // TODO: disconnectButtonsToMainWindow
        break;
    case Pages::FCConfigPage:
        LOGD("here");
        // TODO: disconnectButtonsToMainWindow
        break;
    case Pages::_2DVisionPage:
        LOGD("here");
        // TODO: disconnectButtonsToMainWindow
        break;
    case Pages::_3DViewPage:
        LOGD("here");
        // TODO: disconnectButtonsToMainWindow
        break;
    case Pages::RCPage:
        LOGD("here");
        RcWidget::getInstance().topButtons->disconnectButtonsToMainWindow();
        break;
    case Pages::SerialPage:
        LOGD("here");
        // TODO: disconnectButtonsToMainWindow
        break;
    case Pages::Networkpage:
        LOGD("here");
        NetworkWidget::getInstance().topButtons->disconnectButtonsToMainWindow();
        break;
    case Pages::SettingsPage:
        LOGD("here");
        SettingsWidget::getInstance().topButtons->disconnectButtonsToMainWindow();
        break;
    default :
        qDebug() << "File:" <<  __FILE__ << " Line:"<<  __LINE__ << " Func:" <<  __FUNCTION__;
        qDebug() << "error when disconnect";
        LOGE("error when disconnect");
        break;
    }
    return 0;
}

MainWindow * MainWindow::getWindowByPage(QWidget *pageInstance)
{
    foreach(QWidget *w, qApp->topLevelWidgets())
    {
        if (MainWindow* mainWin = qobject_cast<MainWindow*>(w)){
            LOGD("find MainWindow");
            if(mainWin->mainWindowCentralWidget == pageInstance->parent()){
                LOGD("find instance");
                return mainWin;
            }
        }
    }
    return nullptr;
}

MainWindow * MainWindow::getWindowByPage(Pages::PagesNumber pageType)
{
    QWidget *pageInstance = nullptr;
    switch (pageType) {
    case Pages::HomePage:
        LOGD("here");
        pageInstance = &HomeWidget::getInstance();
        break;
    case Pages::StatusPage:
        LOGD("here");
        pageInstance = &StatusWidget::getInstance();
        break;
    case Pages::ChartPage:
        LOGD("here");
        // TODO: set pageInstance
        break;
    case Pages::FCConfigPage:
        LOGD("here");
        // TODO: set pageInstance
        break;
    case Pages::_2DVisionPage:
        LOGD("here");
        // TODO: set pageInstance
        break;
    case Pages::_3DViewPage:
        LOGD("here");
        // TODO: set pageInstance
        break;
    case Pages::RCPage:
        LOGD("here");
        pageInstance = &RcWidget::getInstance();
        break;
    case Pages::SerialPage:
        LOGD("here");
        // TODO: set pageInstance
        break;
    case Pages::Networkpage:
        LOGD("here");
        pageInstance = &NetworkWidget::getInstance();
        break;
    case Pages::SettingsPage:
        LOGD("here");
        pageInstance = &SettingsWidget::getInstance();
        break;
    default :
        qDebug() << "File:" <<  __FILE__ << " Line:"<<  __LINE__ << " Func:" <<  __FUNCTION__;
        qDebug() << "error when find page";
        LOGE("error when find page");
        break;
    }
    if(pageInstance == nullptr){
        qDebug() << "page not found:" << pageType;
        LOGE("page not found:%d", pageType);
        return nullptr;
    }

    foreach(QWidget *w, qApp->topLevelWidgets())
    {
        if (MainWindow* mainWin = qobject_cast<MainWindow*>(w)){
            LOGD("find MainWindow");
            if(mainWin->mainWindowCentralWidget == pageInstance->parent()){
                LOGD("find instance");
                return mainWin;
            }
        }

    }
    return nullptr;
}

unsigned int MainWindow::getNumberOfAllWindows(void)
{
    unsigned int count = 0;
    foreach(QWidget *w, qApp->topLevelWidgets())
    {
        if (MainWindow* mainWin = qobject_cast<MainWindow*>(w)){
            LOGD("find MainWindow");
            count++;
        }
    }
    return count;
}
